/******************************************************
*  Copyright(c) pages.ilovezxl.top
*  FileName : log.h
*  Author : rivulet.dave
*  Description : LOG功能模块头文件
*  Data : 2019-04-15
******************************************************/

#ifndef __LOG_H__
#define __LOG_H__

/*********************************************************************
 * INCLUDES
 */

#include "salcfg.h"

#ifdef __cplusplus
extern "C" {
#endif

/*********************************************************************
 *  EXTERNAL VARIABLES
 */

/*********************************************************************
 * TYPES
 */

typedef enum _log_level
{
    LOG_LEVEL_DEBUG,    // 调试信息
    LOG_LEVEL_INFO,     // 重要数据信息
    LOG_LEVEL_WARNING,  // 告警信息
    LOG_LEVEL_ERROR,    // 致命错误信息
    LOG_LEVEL_RAW,      // 不加前缀，原样输出
    LOG_LEVEL_INVALID,
} LOG_LEVEL_E;

typedef struct _logbuf_node
{
    uint8_t ucLevel;
    char    acBuffer[LOG_ONELINE_MAX_LEN];
} LOGBUF_NODE_S;

typedef void(*logoutput_callback_t)(const LOGBUF_NODE_S *pLogBuf);

/*********************************************************************
 * MACROS
 */

/* 从文件的完整路径中提取文件名 */
#ifndef __FILENAME__
#if defined (__CC_ARM) || defined (_WIN32)
#define __FILENAME__    (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#else
#define __FILENAME__    (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#endif
#endif

#define LOG_RAW(moduletag, ...)     LOG_Output(moduletag, LOG_LEVEL_RAW, 0, __FILENAME__, __LINE__, ## __VA_ARGS__)
#define LOG_INF(moduletag, ...)     LOG_Output(moduletag, LOG_LEVEL_INFO, 0, __FILENAME__, __LINE__, ## __VA_ARGS__)
#define LOG_DBG(moduletag, ...)     LOG_Output(moduletag, LOG_LEVEL_DEBUG, 0,  __FILENAME__, __LINE__, ## __VA_ARGS__)
#define LOG_WRN(moduletag, ...)     LOG_Output(moduletag, LOG_LEVEL_WARNING,0,  __FILENAME__, __LINE__, ## __VA_ARGS__)
#define LOG_ERR(moduletag, ...)     LOG_Output(moduletag, LOG_LEVEL_ERROR, 0, __FILENAME__, __LINE__, ## __VA_ARGS__)

#define LOG_DUMP(moduletag, pcTitle, puiMsg, uiMsgLen)            \
                LOG_HexDumpOutput((moduletag), 0, (pcTitle), (puiMsg), (uiMsgLen), __FILENAME__, __LINE__)

/*********************************************************************
 * FUNCTIONS
 */

/**
 *   @Description: LOG功能初始化
 *   @param  : ucLevel - 入参， LOG级别
 *   @return : NA
 */
void LOG_Init(uint8_t ucLevel);

/**
 *   @Description: 日志输出
 *   @param : pcModuleName - 输出日志的模块名称
 *   @param : ucLevel - 日志级别
 *   @param : uiKey - 区分不同的缓存区
 *   @param : pcFileName - 文件名
 *   @param : uiLine - 所在行号
 *   @param : format_msg
 *   @return: NA
 */
void LOG_Output(char *pcModuleName, uint8_t ucLevel, uint32_t uiKey, char *pcFileName, uint32_t uiLine, char *pcFormatMsg, ...);

/**
 *   @Description: 以16进制输出数据
 *   @param : pcModuleName - 输出日志的模块名称
 *   @param : uiKey - 区分不同的缓存区
 *   @param : pcTitle - 输出前的标题
 *   @param : puiMsg - 输出的数据
 *   @param : uiMsgLen - 输出的数据的长度
 *   @param : pcFileName - 输出日志的文件名
 *   @param : uiLine - 输出日志的行号
 *   @return: NA
 */
void LOG_HexDumpOutput(char *pcModuleName, uint32_t uiKey, char *pcTitle, const uint8_t *pucMsg, uint32_t uiMsgLen, char *pcFileName, uint32_t uiLine);

/**
 *   @Description: 注册LOG输出的方式
 *   @param : pfLogOutput - 入参，log输出的回调函数
 *   @return: 错误信息
 */
int32_t LOG_OutputRegister(logoutput_callback_t pfLogOutput);

/**
 *   @Description: 取消LOG输出
 *   @param : pfLogOutput - 入参，log输出的回调函数，与注册时的一致
 *   @return: 错误信息
 */
int32_t LOG_OutputUnregister(logoutput_callback_t pfLogOutput);

/**
 *   @Description: 将缓存中的日志写入到文件或输出，调用注册的回调函数
 *   @param : uiLogNum - 入参，一次输出的日志数据，0代表缓存中的所有日志
 *   @return: NA
 */
void LOG_Flush(uint32_t uiLogNum);

#ifdef __cplusplus
}
#endif /* end of __cplusplus */

#endif
/************************************** The End Of File **************************************/

